package com.thoughtworks.recruit.test.jgraph.interfaces;

import java.util.Set;

/**
 * A graph whose all edges are directed. This is the root interface of all directed graphs.
 *
 *
 * @param <V> the graph vertex type
 * @param <E> the graph edge type
 *
 */
public interface DiGraph<V, E>
    extends Graph<V, E>
{
    /**
     * Returns the "in degree" of the specified vertex. An in degree of a vertex in a directed graph
     * is the number of inward directed edges from that vertex.
     *
     * @param vertex vertex whose degree is to be calculated.
     *
     * @return the degree of the specified vertex.
     */
    int inDegreeOf(V vertex);

    /**
     * Returns a set of all edges incoming into the specified vertex.
     *
     * @param vertex the vertex for which the list of incoming edges to be returned.
     *
     * @return a set of all edges incoming into the specified vertex.
     */
    Set<E> incomingEdgesOf(V vertex);

    /**
     * Returns the "out degree" of the specified vertex. An out degree of a vertex in a directed
     * graph is the number of outward directed edges from that vertex.
     *
     * @param vertex vertex whose degree is to be calculated.
     *
     * @return the degree of the specified vertex.
     */
    int outDegreeOf(V vertex);

    /**
     * Returns a set of all edges outgoing from the specified vertex.
     *
     * @param vertex the vertex for which the list of outgoing edges to be returned.
     *
     * @return a set of all edges outgoing from the specified vertex.
     */
    Set<E> outgoingEdgesOf(V vertex);

    /**
     * An interface for a graph whose edges have non-uniform weights.
     *
     * @param <V> the graph vertex type
     * @param <E> the graph edge type
     *
     */
    interface WeightedGraph<V, E>
        extends Graph<V, E>
    {
        /**
         * The default weight for an edge.
         */
        double DEFAULT_EDGE_WEIGHT = 1.0d;

        /**
         * Assigns a weight to an edge.
         *
         * @param e edge on which to set weight
         * @param weight new weight for edge
         */
        void setEdgeWeight(E e, double weight);
    }
}
